package com.badrit.core.visualization  
{
	  
    import com.badrit.core.clusteringAlgorithms.BaseClusteringAlgorithm;
    import com.badrit.core.clusteringAlgorithms.KMeans;
    import com.vizsage.as3mathlib.math.alg.Matrix;
    
    import flash.events.Event;
    
    import org.papervision3d.core.geom.Lines3D;
    import org.papervision3d.core.geom.renderables.Line3D;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.special.LineMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
  
    [SWF(backgroundColor="#000000",width="425",height="350")]    
    public class PointsPlot extends BasicView 
    {	
        public var chartContainer:DisplayObject3D;
        public var chart:DisplayObject3D;
        private var dataPoints : Array;
         
        private static const RADIUS : int = 5;
        private static const MAX_SIZE : int = 600; 
        private static const AXIS_SIZE : int = 800; 
        
        public var scaleFactor:Number = 50;  
        
        private var cachedPatterns:Matrix;
        private var cachedClusteringAlgorithm:BaseClusteringAlgorithm;              
   
        public function PointsPlot(width:int, height:int,
        			patterns:Matrix=null, clusteringAlgorithm:KMeans=null)
        {
        	super(width, height, false, true);
        	update(patterns, clusteringAlgorithm); 
        }  
   
   		public function update(
   				patterns:Matrix = null, 
   				clusteringAlgorithm:BaseClusteringAlgorithm=null):void{
   			
   			if(patterns == null){
   				if( cachedPatterns == null ){
   					patterns = new Matrix(0, 0);   				
   				} else {
   					patterns = cachedPatterns;		
   				}
   			} else {
   				cachedPatterns = patterns;
   			}
   			
   			if(clusteringAlgorithm == null){
   				clusteringAlgorithm = cachedClusteringAlgorithm;
   			} else {
   				cachedClusteringAlgorithm = clusteringAlgorithm;   			
   			}
   			
   			
   			
   			if(chart != null){
   				for each( var child:DisplayObject3D in chart.children )
				{
					chart.removeChild( child );					
				}
   			}
   			
   			chartContainer = new DisplayObject3D("Chart Container");
	        chart = new DisplayObject3D("Chart");
	         
	        chartContainer.rotationY=-1;
	        chartContainer.rotationX=-10;
	        dataPoints = new Array(); 
    
		    var defaultMaterial : LineMaterial = new LineMaterial(0xFFFFFF, .1);
		    var xAxisMaterial : LineMaterial = new LineMaterial( 0xFF0000, .75 );
		    var yAxisMaterial : LineMaterial = new LineMaterial( 0x00FF00, .75 );
		    var zAxisMaterial : LineMaterial = new LineMaterial( 0x0000FF, .75 );          
        
            var axes : Lines3D = new Lines3D( defaultMaterial, "Axes" );
            axes.addLine( new Line3D( axes, xAxisMaterial, 2, new Vertex3D( -AXIS_SIZE,0,0 ), new Vertex3D( AXIS_SIZE,0,0 ) ));
            axes.addLine( new Line3D( axes, yAxisMaterial, 2, new Vertex3D( 0,-AXIS_SIZE,0 ), new Vertex3D( 0,AXIS_SIZE,0 ) ));
            axes.addLine( new Line3D( axes, zAxisMaterial, 2, new Vertex3D( 0,0,-AXIS_SIZE ), new Vertex3D( 0,0,AXIS_SIZE ) ));
            
                                
          
            chart.addChild( axes );      
            
            var clusterColors:Array = new Array(
            			0xFF0000,
            			0x00FF00,
            			0x0000FF,
            			0x0F7F00,
            			0xF70F90,
            			0x09FFEE,
            			0xFFFF00,
            			0xFFFFFF,
            			0xFFFFFF
            		);    
          
            var lastVertex : Vertex3D;
            var currentVertex : Vertex3D = new Vertex3D();
          
	        for(var i:int; i < patterns.$rows; i++)
	        {	        	
	         	var pattern:Array = patterns.$m[i];
	         	var classId:int ;
	         	if(clusteringAlgorithm != null){
	         		classId = clusteringAlgorithm.getClusterForPattern(i);
	         	} else {
	         		classId = 5;
	         	}
	         	
	         	if( isNaN(clusterColors[classId])){
	         		clusterColors[classId] = 0x000000;
	         	}
	         	
				var dataMaterial:ColorMaterial = 
						new ColorMaterial( clusterColors[classId], 1, false );
						         	         	         
	            var point : Sphere = new Sphere( dataMaterial, RADIUS );
	            point.x = pattern[0] * scaleFactor;
	            point.y = pattern[1] * scaleFactor;
	            if(isNaN(pattern[2])){
	            	point.z = 0;
	            } else {
	            	point.z = pattern[2] * scaleFactor;
	            }
	            
	            
	            chart.addChild( point );                         
          	}
    
			chartContainer.addChild(chart);
			scene.addChild(chartContainer); 
			
			singleRender(); 
    
    		if(!hasEventListener(Event.ENTER_FRAME))
          		addEventListener(Event.ENTER_FRAME, onEnterFrame); 
   		}
   		
        private function onEnterFrame(e:Event): void 
        {
        	chart.rotationY+=1; 
        	singleRender(); 
        }
      
        private function positiveOrNegative() : int
       	{
        	var seed : Number = Math.random() * 100;
         	if ( seed > 50 )
           		return 1;
         	else 
           		return -1;
       	} 
    }
}